package cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.artist;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.spring.injection.annot.SpringBean;

import cz.muni.fi.pa165.musiclibrary.api.service.IArtistService;
import cz.muni.fi.pa165.musiclibrary.api.service.ISongService;
import cz.muni.fi.pa165.musiclibrary.api.service.auth.IUser;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IAlbumDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IArtistDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.ISongDTO;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.MusicLibrarySession;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.ArtistFormPanel;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.ConfirmationLink;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.FormSubmittedEvent;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.AbstractMusicLibraryPage;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.album.AlbumPage;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.search.SearchPage;

/**
 *
 * @author Maros Kucbel
 * @date 2012-11-23T21:20:06+0100
 */
public final class ArtistPage extends AbstractMusicLibraryPage {

    @SpringBean
    private IArtistService artistService;
    @SpringBean
    private ISongService songService;
    
    public ArtistPage() {
        this(new PageParameters());
    }
    
    public ArtistPage(final PageParameters pageParameters) {
        super(pageParameters);
    }

    @Override
    public void renderHead(IHeaderResponse response) {
        
        response.render(CssHeaderItem.forReference(new CssResourceReference(ArtistPage.class, "ArtistPage.css")));
        super.renderHead(response);
    }
    
    @Override
    protected void onInitialize() {
        super.onInitialize();
        this.initializeComponents();
    }

    private void initializeComponents() {
        Integer id = this.getPageParameters().get("id").toOptionalInteger();
        if (id == null) {
            throw new RestartResponseException(SearchPage.class);
        }
        final IArtistDTO artist = artistService.getById(new Long(id));
        if (artist == null) {
            throw new RestartResponseException(SearchPage.class);
        }
        Set<IAlbumDTO> albumsSet = new HashSet<IAlbumDTO>();
        List<ISongDTO> songs = songService.getByArtist(artist);
        for(ISongDTO song : songs) {
            if(!albumsSet.contains(song.getAlbum())) {
                albumsSet.add(song.getAlbum());
            }
        }
        List<IAlbumDTO> albumsList = new ArrayList<IAlbumDTO>();
        albumsList.addAll(albumsSet);
        add(new Label(ComponentIDs.ARTIST_NAME, artist.getName()));
        add(new Label(ComponentIDs.ARTIST_DESCRIPTION, artist.getDescription()));

        ListView<IAlbumDTO> albumsView = new ListView<IAlbumDTO>(ComponentIDs.ALBUMS_LIST, albumsList) {

            @Override
            protected void populateItem(ListItem<IAlbumDTO> item) {
                IAlbumDTO album = item.getModelObject();
                PageParameters params = new PageParameters();
                params.add("id", album.getIdAlbum().toString());
                Link<Void> albumLink = new BookmarkablePageLink<Void>(ComponentIDs.ALBUM_LINK, AlbumPage.class, params);
                albumLink.add(new Label(ComponentIDs.ALBUM_LINK_NAME, album.getTitle()));
                item.add(albumLink);
            }
        };
        add(albumsView);
        
        MusicLibrarySession session = MusicLibrarySession.get();
        final ModalWindow artistWindow = new ModalWindow(ComponentIDs.EDIT_ARTIST_MODAL) {
            
            @Override
            public void show(AjaxRequestTarget target) {
                this.setContent(new ArtistFormPanel(this.getContentId(), artist));
                super.show(target);
            }
        };
        this.add(artistWindow);
        artistWindow.setTitle(new StringResourceModel("ArtistPage.editArtist.modal.title", this, null));
        artistWindow.setMinimalWidth(500);
        artistWindow.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
        AjaxLink editArtist = new AjaxLink(ComponentIDs.EDIT_ARTIST_MODAL_LINK) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                artistWindow.show(target);
            }

            @Override
            public void onEvent(IEvent<?> event) {
                if (artistWindow.isShown() && event.getPayload() instanceof FormSubmittedEvent) {
                    FormSubmittedEvent submitted = (FormSubmittedEvent) event.getPayload();
                    artistWindow.close(submitted.getTarget());
                    ArtistPage.this.setResponsePage(ArtistPage.class, ArtistPage.this.getPageParameters());
                }
            }
            
        };
        editArtist.setVisible(session.isAuthorized());
        this.add(editArtist);
        
        String deleteMessage = new StringResourceModel("ArtistPage.deleteArtist.confirmation.message", this, null).getObject();
        ConfirmationLink<IArtistDTO> deleteArtist = new ConfirmationLink<IArtistDTO>(ComponentIDs.DELETE_ARTIST_LINK, deleteMessage) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                try {
                    IUser user = MusicLibrarySession.get().getUser();
                    String userName = user != null ? user.getUserName() : null;
                    ArtistPage.this.artistService.delete(artist, userName);
                    this.setResponsePage(SearchPage.class);
                } catch (Exception ex) {
                    String errorMessage = new StringResourceModel("database.delete.error", this, null).getObject();
                    target.appendJavaScript("alert('" + errorMessage + "');");
                }
            }
        };
        deleteArtist.setVisible(session.isAuthorized());
        this.add(deleteArtist);
    }
    
    private static final class ComponentIDs {
        
        private static final String ARTIST_NAME = "artistName";
        
        private static final String ARTIST_DESCRIPTION = "artistDescription";
        
        private static final String ALBUMS_LIST = "albumsList";
        
        private static final String ALBUM_LINK = "albumLink";
        
        private static final String ALBUM_LINK_NAME = "albumLinkName";
        
        private static final String EDIT_ARTIST_MODAL = "editArtistModal";
        private static final String EDIT_ARTIST_MODAL_LINK = "editArtistModalLink";
        
        private static final String DELETE_ARTIST_LINK = "deleteArtistLink";
        
    }
    
}